#encoding=utf8
import Image
import cStringIO
import datetime
from django.contrib.auth import *
from django.contrib.auth.models import *
from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage
from django.db import transaction
from django.db.models import Q
from django.http import *
from django.shortcuts import *
import httplib
import json
import logging
import os
import uuid

from trp.models import *
from trp.views.strategy import get_material_list
from utils.JsonResponse import *
from utils.MaterialUploadHanler import *
from utils.decorators import *
from utils.utils import *
from website.settings import MATERIAL
from website.settings import LOGGER as logger


from trp.views.strategy import get_default_resource_strategy,get_default_traffic_strategy

logger = logging.getLogger(__name__)

@login_required
def main(request):
    isPlatformAdmin=request.user.account.admin and (OrgType.PLATFORM in request.user.account.organization.values_list("type",flat=True))
    print isPlatformAdmin
    if isPlatformAdmin :
        return render_to_response("trp/material_admin.html",{'user' : request.user, 'page' : 'material'})
    else :
        return render_to_response("trp/material_vendor.html",{'user' : request.user, 'page' : 'material'})


@login_required_ajax
@transaction.atomic
def do_create(request):
    param =None
    try :
        param = json.loads(request.body)
        with transaction.atomic():
            for m in param["materials"]:
                __save_material(request,param, m)
    except Exception,e:
        logger.exception(e)
        return JsonResponseBadrequest({"message":str(e)})
    return JsonResponse({"message":"ok"})

@login_required_ajax
def upload(request):
    try :
        res_arr = []
        files = request.FILES
        handler = ImgUploadHandler()
        handler.set_processor(FlashUploadHandler()).set_processor(HtmlUploadHandler())
        if files :
            for f in files.values():
                req = UploadRequest(f)
                res = handler.handle(req)
                res_arr.append(res)
        else :
            raise Exception("no material uploaded")
#         TODO 物料格式定义
        if len(files) ==1 :
            return JsonResponse(res_arr[0])
        else :
            return JsonResponse({"materials":res_arr})
    except Exception,e:
        logger.exception(e)
        return JsonResponseBadrequest({"message":str(e)})


@login_required_ajax
@transaction.atomic
def do_modify(request):
    try :
        param =json.loads(request.body)
        material_id = param.get("material_id")
        name=param.get("name")
        landingpage = param.get("landingpage")
        frequency=param.get("frequency",0)
        tags = param.get("tags")
        if not name or not landingpage :
            raise Exception("name or landingpage is empty") 
        with transaction.atomic():
            material = Material.objects.get(pk=int(material_id),deleted=False)
            material.name = name 
            ldp = material.landingpage
            material.landingpage = landingpage
            material.frequency=frequency
            if landingpage != ldp :
                material.status=0

            if tags :
                tags_db = __tag_arr(tags)
                material.tags.clear()
                material.tags = tags_db
            material.save()
#
            if landingpage != ldp :
                __update_material_weight(material)
            operation_log=OperationLog()
            operation_log.operation="修改"
            operation_log.object="素材"
            operation_log.user=request.user    
            operation_log.object_id=material_id 
            operation_log.save()
            return JsonResponse({"message":"ok"})
    except Exception,e:
        logger.exception(e)
        return JsonResponseBadrequest({"message":str(e)})


@login_required_ajax
@transaction.atomic
def do_audit(request):
    account = request.user.account
    if not (OrgType.PLATFORM in account.organization.values_list("type",flat=True)) or not account.admin:
        raise Exception("no auth")
    try :
        param = json.loads(request.body)
        mid = int(param.get("material_id",-1))
        status = param.get("status",0)
        reason = param.get("reason")or ""
        with transaction.atomic():
            m = Material.objects.get(pk=mid,deleted=False)
            status = int(status)
            if status>0 and status<3 :
                m.status=status
                if m.status==1:
                    details="审核素材通过"
                else:
                    details="审核素材拒绝"
            else :
                raise Exception("material status illegal")
            if status ==2 and not reason :
                raise Exception("reason cannot be empty when reject")
            m.reason = reason
            m.save()
            __update_material_weight(m)
        operation_log=OperationLog()
        operation_log.operation="审核"
        operation_log.object="素材"
        operation_log.user=request.user
        operation_log.details=details      
        operation_log.object_id=mid 
        operation_log.save()        

    except Exception,e:
        logger.exception(e)
        return JsonResponseBadrequest({"message":str(e)})
    return JsonResponse({"message":"ok"})

#更新物料权重时间戳
def __update_material_weight(m):
    objs = MaterialWeight.objects.filter(material=m)
    for obj in objs:
        obj.strategy.save()

@login_required_ajax
def get_material(request):
    param =None
    try :
        param = json.loads(request.body)
        mid = param.get("material_id")
        m = {}
        material = Material.objects.prefetch_related("tags").get(pk=int(mid))
        m["id"]=material.id
        m["name"]=material.name
        m["width"]=material.width
        m["height"]=material.height
        m["status"]=material.status
        m["url"]=material.url
        m["reason"]=material.reason
        m["frequency"]=material.frequency
        m["tags"]=[{"id":tag.id,"name":tag.name} for tag in material.tags.all() or []]
        m["landingpage"]=material.landingpage

        if not m['landingpage'].startswith("http://") and not m['landingpage'].startswith("https://"):
            m['landingpage'] = "http://" + m['landingpage']

        return JsonResponse(m)
    except Exception,e:
        logger.exception(e)
        return JsonResponseBadrequest(param)

@login_required_ajax
def get_materials(request):
    isPlatformAdmin=request.user.account.admin and (OrgType.PLATFORM in request.user.account.organization.values_list("type",flat=True))
    param = json.loads(request.body)
    searchTxt = param.get("search_text","")
    status = param.get("status",-1)
    size  = param.get("size","")
    width = param.get("width")
    height= param.get("height")
    pageNo = param.get('pageNo',1)
    pageSize = param.get("pageSize",20)
    orderBy = param.get("orderBy","id")
    order = param.get("order","desc")
    type = param.get("type")
    if orderBy :
        orderBy = (order =="asc" and "" or "-") + orderBy

    qset = Material.objects.select_related().filter(deleted=False)
    if type!=None and type!="":
        qset=qset.filter(type_id=int(type))
    if not isPlatformAdmin :
        qset = qset.prefetch_related("tags")
    if status and int(status)!=-1 :
        qset = qset.filter(status=int(status))
    if width and height :
        qset = qset.filter(width =int(width),height=int(height))
    if isPlatformAdmin :
        if searchTxt :
            try:
                mid=int(searchTxt)
                qset = qset.filter(Q(name__icontains=searchTxt) |
                                           Q(id=mid)|Q(creator__username__icontains=searchTxt))
            except:
                qset = qset.filter(Q(name__icontains=searchTxt) |
                                            Q(creator__username__icontains=searchTxt))
        if size :
            sizeArr=split_to_int_array(size,sep="x")
            qset = qset.filter(width=sizeArr[0],height=sizeArr[1])
    else :
        if searchTxt :
            try:
                mid=int(searchTxt)
                qset = qset.filter(Q(name__icontains=searchTxt)|
                        Q(tags__name__icontains=searchTxt)|Q(id=mid)).distinct()
            except:
                qset = qset.filter(Q(name__icontains=searchTxt)|
                        Q(tags__name__icontains=searchTxt)).distinct()
        orgIds = request.user.account.organization.values_list("id",flat=True)

        qset = qset.filter(organization__in = orgIds)

    if orderBy :
        qset = qset.order_by(orderBy)
    qset= qset.distinct()

    paginator = Paginator(qset, pageSize)
    try:
        data = paginator.page(pageNo)
    except PageNotAnInteger:
        data = paginator.page(1)
    except EmptyPage:
        data = paginator.page(paginator.num_pages)
    dataArr=[]

    if  data:
        for ele in data.object_list:
            ele_n = {}
            ele_n["id"]=ele.id
            ele_n["name"]=ele.name
            ele_n["width"]=ele.width
            ele_n["height"]=ele.height
            ele_n["status"]=ele.status
            ele_n["landingpage"]=ele.landingpage
            ele_n["frequency"]=ele.frequency
            if not ele_n['landingpage'].startswith("http://") and not ele_n['landingpage'].startswith("https://"):
                ele_n['landingpage'] = "http://" + ele_n['landingpage']
            ele_n["reason"] = ele.reason
            ele_n["size"]=ele.size
            if isPlatformAdmin :
                ele_n["upload_time"]=ele.upload_time.strftime("%Y-%m-%d %H:%M:%S")
                #ele_n["uploader"]=ele.organization.name
                ele_n["uploader"]=""
                if ele.creator:
                    ele_n["uploader"]=ele.creator.username
                ele_n["type"]=ele.type and ele.type.name
            else :
                ele_n["type"]=ele.type and ele.type.name
                ele_n["tags"]=[tag.name for tag in ele.tags.all()]

            dataArr.append(ele_n)
    result={}
    result["bodyData"]=dataArr
    result["pageSize"]=pageSize
    result["pageNo"]=pageNo
    result["totalCount"]=paginator.count
    return JsonResponse(result)

@login_required_ajax
def get_material_available_by_position(request):
    param = json.loads(request.body)
    traffic_id= param.get("traffic_id")
    traffic=Traffic.objects.get(pk=traffic_id)
    ids=[]
    ids.append(traffic_id)
    result={}
    strategy_ids = ResourcePrice.objects.filter(resource__in=traffic.TRAFFIC.all()).values_list("strategy_id",flat=True)
    strategys = Strategy.objects.filter(Q(priority__lt=0),id__in=strategy_ids,deleted=False)
    sid=strategys[0].id
    datalist=get_material_list(ids,sid)
    result["bodyData"]=datalist
    return JsonResponse(result)

@login_required_ajax
@transaction.atomic
def set_default_material(request):    
    result={}
    params = json.loads(request.body)
    rid=params.get("resource_id")
    tid=params.get("traffic_id")    
    groups = params.get("groups")
    material_weight_arr  = __parse_material_weight(groups)
    default_strategy=None
    operation_log=OperationLog()
    operation_log.operation="素材设置"
    operation_log.user=request.user
    details="默认素材设置成功"
    if rid:
        rid=int(rid)
        default_strategy = get_default_resource_strategy(rid)     
        operation_log.object="分片"                    
        operation_log.object_id=rid        
    elif tid:
        tid=int(tid)
        default_strategy=get_default_traffic_strategy({"tid":tid})  
        operation_log.object_id=tid
        operation_log.object="流量" 
    if default_strategy:
        if material_weight_arr :
#             for mw in material_weight_arr:
#                  details+=str(mw)
            default_strategy.set_material_weights(material_weight_arr)
        else :
            default_strategy.set_material_weights([])
        operation_log.details=details  
        operation_log.save()
    return JsonResponse(result)

def __parse_material_weight(groups):
    material_weight_arr = []
    weight =0
    for group in groups :
        materials = group["materials"]
        weight= (int(group["weight"])*100)/len(materials)
        for m in materials:
            tmp = {}
            tmp["group"]=group["name"]
            tmp["weight"]=weight
            tmp["material_id"]=int(m)
            material_weight_arr.append(tmp)    
    return material_weight_arr


@login_required
def get_material_type(request):
    type_arr=[]
    try:
        types = MaterialType.objects.all()
        for t in  types :
            tmp = {}
            tmp["id"]=t.id
            tmp["name"]=t.name
            type_arr.append(tmp)
    except Exception,e:
        logger.exception(e)
        return JsonResponseBadrequest({"message":"bad request"})

    return JsonResponse({"data":type_arr})


def __tag_arr(strs):
    """
    根据strs（csv格式的字符串）获取数据库中的tag，没有则创建
    """
    if strs :
        str_arr=remove_none(strs.split(","))
        for s in str_arr :
            MaterialTag.objects.get_or_create(name=s)
        return MaterialTag.objects.filter(name__in=str_arr)
    return MaterialTag.objects.none()

def __save_material(request,param,m):
    """
    保存物料信息到数据库
    """
    width =m["width"]
    height=m["height"]
    name=m["name"]
    size = m["size"]
    t=m["type"]
    url=m["url"]
    frequency=0
    if m.get("frequency")!=None and m.get("frequency")!="":
        frequency=int(m["frequency"])
    else:
        if param.get("frequency")!=None and param.get("frequency")!="":
            frequency=int(param.get("frequency"))

    if not name :
        raise Exception("name can not be empty")

    if not url :
        raise Exception("url can not be empty")
    landingpage= (m.get("landingpage") or param.get("landingpage"))
    if not landingpage :
        raise Exception("landingpage can not be empty")

    if not landingpage.startswith('http://') and not landingpage.startswith('https://'):
        landingpage = 'http://' + landingpage

    tags = __tag_arr(m.get("tags") or param.get("tags"))

    org = request.user.account.get_organization()
    t_obj = MaterialType.objects.get(pk=int(t))
    creator=request.user
    material = Material(name=name,
                 width=int(width),
                 height=int(height),
                 size=int(size),
                 type=t_obj,
                 url=url,
                 landingpage=landingpage,
                 status=0,
                 organization=org,
                 upload_time=datetime.datetime.now(),
                 creator=creator,frequency=frequency)
    material.save()
    material.tags = tags
    
    operation_log=OperationLog()
    operation_log.operation="新建"
    operation_log.object="素材"
    operation_log.user=request.user    
    operation_log.object_id=material.id 
    operation_log.save()

@login_required_ajax
def get_material_size(request):
    try :
        org = request.user.account.organization.all()[0]
        size_lst=None
        if org.type ==OrgType.PLATFORM and request.user.account.is_admin():
            size_lst  = Material.objects.filter(deleted=False).values_list("width","height").order_by("width","height").distinct()
        else :
            size_lst = Material.objects.filter(organization__in= request.user.account.organization.all(),deleted=False).values_list("width","height").order_by("width","height").distinct()
        data_arr =[]
        for s in size_lst :
            tmp = {}
            tmp["width"]=s[0]
            tmp["height"]=s[1]
            data_arr.append(tmp)
        return JsonResponse({"data":data_arr})
    except Exception,e:
        logger.exception(e)
        return JsonResponseBadrequest({"message":str(e)})
